/**
 @file sys_usw_chip.c

 @date 2009-10-19

 @version v2.0

 The file define APIs of chip of sys layer
*/
/****************************************************************************
 *
 * Header Files
 *
 ****************************************************************************/
#include "ctc_error.h"
#include "ctc_register.h"
#include "ctc_warmboot.h"
#include "ctc_hash.h"
#include "sys_usw_common.h"
#include "sys_usw_register.h"
#include "sys_usw_dmps.h"
#include "sys_usw_ftm.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_port_api.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_dma.h"
#include "sys_usw_acl_api.h"
#include "sys_usw_l2_fdb.h"
#include "drv_api.h"
/****************************************************************************
 *
 * Global and static
 *
 *****************************************************************************/
sys_chip_master_t* p_usw_chip_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};
extern uint8 g_lchip_num;
extern uint8 g_ldev_num;
extern ctc_wb_master_t *g_wb_master[CTC_MAX_LOCAL_CHIP_NUM_PP];
extern int32 dal_get_chip_dev_id(uint8 lchip, uint32* dev_id);
extern bool dal_get_soc_active(uint8 lchip);
extern uint8 dal_device_get_pp_num(uint8 lchip);
extern int32 drv_chip_pci_intf_adjust_en(uint8 lchip, uint8 enable);
extern int32 drv_sdb_read_from_hw(uint8 lchip, uint8 enable);
extern int32 sys_usw_packet_set_cpu_mac(uint8 lchip, uint8 idx, uint32 gport, mac_addr_t da, mac_addr_t sa, uint16 vlan_id, uint16 tpid);
extern int32 dal_knet_set_wb_reloading(uint8 lchip, uint32 reloading_proc);
extern int32 ctc_pmem_remmap(uint8 lchip, ctc_wb_master_t *p_wb_master);
extern int32 sys_usw_dtel_free_task(uint8 lchip);
extern int32 sys_usw_interrupt_free_task(uint8 lchip);
extern int32 sys_usw_scl_free_inner_group(uint8 lchip);


int8 g_vchip_inited[CTC_MAX_LOCAL_CHIP_NUM_PP]={0};
sys_chip_info_t sys_chip_info[CTC_MAX_LOCAL_CHIP_NUM_PP];

#define TBL_CLASS_H(module, bit)  \
uint16 module##_feature_mode_tbl[] = {

#define TBL_CLASS_END \
  };

#define TBL_CLASS_D(feature, tbl_id, mem_type) \
    tbl_id,

#include "arctic/sys_at_tbl_class.h"

/****************************************************************************
 *
 * Function
 *
 *****************************************************************************/
STATIC int32 _sys_usw_chip_init_ser(uint8 lchip, ctc_chip_global_cfg_t* p_cfg);
/**
 @brief The function is to initialize the chip module and set the local chip number of the linecard
*/

STATIC int32
_sys_usw_chip_dump_db(uint8 lchip, sal_file_t p_f, ctc_global_dump_db_t* p_dump_param)
{
    uint8 i = 0;
    uint8 enable = 0;
    uint8 cpu_eth_chan = 0;
    sys_usw_get_chip_cpu_eth_en(lchip, &enable, &cpu_eth_chan);

    SYS_DUMP_DB_LOG(p_f, "%s\n", "# Chip");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","g_chip_id",p_usw_chip_master[lchip]->g_chip_id);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","cut_through_en",p_usw_chip_master[lchip]->cut_through_en);
    SYS_DUMP_DB_LOG(p_f, "%-30s:0x%04x\n","tpid",p_usw_chip_master[lchip]->tpid);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","cpu_eth_en",p_usw_chip_master[lchip]->cpu_eth_en);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","cpu_channel",cpu_eth_chan);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","vlan_id",p_usw_chip_master[lchip]->vlan_id);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%"PRIu64"\n","alpm_affinity_mask",p_usw_chip_master[lchip]->alpm_affinity_mask);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%"PRIu64"\n","normal_affinity_mask",p_usw_chip_master[lchip]->normal_affinity_mask);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%s\n","cpu_mac_sa",sys_output_mac(p_usw_chip_master[lchip]->cpu_mac_sa));
    SYS_DUMP_DB_LOG(p_f, "%-30s:","cut_through_speed");
    for(i = 0; i < CTC_PORT_SPEED_MAX; i ++)
    {
        SYS_DUMP_DB_LOG(p_f, "[%u,%u]", p_usw_chip_master[lchip]->cut_through_speed[i].port_speed,p_usw_chip_master[lchip]->cut_through_speed[i].enable);
    }
    SYS_DUMP_DB_LOG(p_f, "\n");
    SYS_DUMP_DB_LOG(p_f, "%-40s\n", "Cpu mac da:");
    SYS_DUMP_DB_LOG(p_f, "%-15s%-10s\n", "Index", "Cpu mac da");
    for(i = 0; i < SYS_USW_MAX_CPU_MACDA_NUM; i++)
    {
        SYS_DUMP_DB_LOG(p_f, "%-15u", i);
        SYS_DUMP_DB_LOG(p_f, "%s\n", sys_output_mac(p_usw_chip_master[lchip]->cpu_mac_da[i]));
    }
    SYS_DUMP_DB_LOG(p_f, "%s\n", "----------------------------------------------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");
    return CTC_E_NONE;
}

int32
sys_usw_chip_init_done(uint8 lchip)
{
    uint32 wb_status;

    if (!CTC_WB_ENABLE(lchip))
    {
        drv_get_warmboot_status(lchip, &wb_status);
        if(CTC_WB_STATUS_RELOADING == wb_status)
        {
            return CTC_E_NONE;
        }
    }
#if (0 == SDK_WORK_PLATFORM)
    CTC_ERROR_RETURN(sys_usw_chip_set_active(lchip, TRUE));
#endif
    /*interrupt init done should be before dma init done*/
    CTC_ERROR_RETURN(sys_usw_interrupt_init_done(lchip));

    CTC_ERROR_RETURN(sys_usw_dma_init_done(lchip, 0));
    CTC_ERROR_RETURN(drv_sdb_set_init_done(lchip));
    CTC_ERROR_RETURN(sys_usw_acl_init_done(lchip));
    CTC_ERROR_RETURN(sys_usw_l2_fdb_init_done(lchip));
    if(CTC_WB_ENABLE(lchip) && DRV_IS_TSINGMA(lchip))
    {
        PcieSwitchCtl_m tmp_bug;
        uint32 cmd = DRV_IOR(PcieSwitchCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &tmp_bug);
        SetPcieSwitchCtl(V, cfgReleasePcieSup_f, &tmp_bug, 1);
        cmd = DRV_IOW(PcieSwitchCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &tmp_bug);
    }
    if (DRV_FROM_TMM(lchip))
    {
        uint32 cmd = 0;
        IpeFwdCtl_m ipe_fwd_ctl;
        EpeHdrAdjustCtl_m epe_hdr_adj_ctl;

        cmd = DRV_IOR(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipe_fwd_ctl));
        SetIpeFwdCtl(V, elephantFlowIdLogEn_f, &ipe_fwd_ctl, (DRV_FROM_AT(lchip))?1:(!MCHIP_FEATURE_EN(lchip, CTC_FEATURE_SRV6))); /*disable efd flow id log en*/
        cmd = DRV_IOW(IpeFwdCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipe_fwd_ctl));

        cmd = DRV_IOR(EpeHdrAdjustCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_hdr_adj_ctl));
        SetEpeHdrAdjustCtl(V, flexEditPtrDis_f, &epe_hdr_adj_ctl, (DRV_FROM_AT(lchip))?1:(!MCHIP_FEATURE_EN(lchip, CTC_FEATURE_SRV6))); /*enable flex edit ptr for srv6*/
        cmd = DRV_IOW(EpeHdrAdjustCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_hdr_adj_ctl));
    }

    if (!DRV_FROM_TMM(lchip))
    {
        uint32 field_value  = 0;
        uint32 cmd          = 0;
        uint8 gchip         = 0;
        BufferStoreCtl_m buf_stro_ctl;
        if(p_usw_chip_master[lchip]->cpu_eth_en)
        {
            /*reserve dsfwd resource, need to alloc dsfwd only the first time*/
            cmd = DRV_IOR(IpePpCtl_t, IpePpCtl_iloopCcDsFwdPtr_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
            if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
            {
                CTC_ERROR_RETURN(sys_usw_nh_alloc_from_position(lchip, SYS_API_NH_DSFWD, 1, field_value));
            }
            else if(0 == GetBufferStoreCtl(V, cpuRxPortModeEn_f, &buf_stro_ctl) && field_value == 0)
            {
                CTC_ERROR_RETURN(sys_usw_nh_alloc(lchip, SYS_API_NH_DSFWD, 1, &field_value));
            }
            /*eth cpu port, must set crossconnect in port init*/
            cmd = DRV_IOW(IpePpCtl_t, IpePpCtl_iloopCcDsFwdPtr_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

            sys_usw_get_gchip_id(lchip, &gchip);
            CTC_ERROR_RETURN(sys_usw_port_set_internal_property(lchip, CTC_MAP_LPORT_TO_GPORT(gchip, p_usw_chip_master[lchip]->cpu_lport), SYS_PORT_PROP_ETH_TO_CPU_ILOOP_EN, field_value));
        }
    }
    return CTC_E_NONE;
}

int32 sys_chip_init_vchip(uint8 lchip, uint32 vchip_bmp, uint8 ldev)
{
    uint8 i = 0;
    uint8 vchip_num = 0;
    uint32 pp_bmp = 0;
    sal_memset(&sys_chip_info[lchip], 0, sizeof(sys_chip_info_t));
    for (i = 0; i < DRV_MAX_PP_NUM; i++)
    {
        if (DRV_IS_BIT_SET(vchip_bmp, i))
        {
            sys_chip_info[i + lchip].map_ldev  = ldev;
            sys_chip_info[i + lchip].pp_base = lchip;
            DRV_BIT_SET(pp_bmp, (i + lchip) % 4);
            vchip_num++;
        }
    }

    for (i = 0; i < DRV_MAX_PP_NUM; i++)
    {
        if (DRV_IS_BIT_SET(vchip_bmp, i))
        {
            sys_chip_info[i + lchip].pp_num = vchip_num;
        }
    }

    return DRV_E_NONE;
}


int32
sys_usw_vchip_init(uint8 lchip)
{
    uint8 pp_num = dal_device_get_pp_num(SYS_MAP_LDEV(lchip));
    drv_init_vchip(lchip, (1 << pp_num) - 1, SYS_MAP_LDEV(lchip));
    sys_chip_init_vchip(lchip, (1 << pp_num) - 1, SYS_MAP_LDEV(lchip));
    if (g_vchip_inited[SYS_MAP_LDEV(lchip)] == 0)
    {
        if (lchip+pp_num > g_lchip_num)
        {
            g_lchip_num = lchip+pp_num;
        }
        g_vchip_inited[SYS_MAP_LDEV(lchip)] = 1;
    }
    return CTC_E_NONE;
}

int32
sys_usw_chip_init(uint8 lchip, uint8 lchip_num)
{
    int32 ret;

    if ((lchip >= CTC_MAX_LOCAL_CHIP_NUM_PP)
        || (lchip_num > CTC_MAX_LOCAL_CHIP_NUM_PP))
    {
        return CTC_E_INVALID_CHIP_NUM;
    }

    /* check init */
    if (NULL != p_usw_chip_master[lchip])
    {
        return CTC_E_NONE;
    }

#if (1 == SDK_WORK_PLATFORM)
    CTC_ERROR_RETURN(sys_usw_chip_set_active(lchip, TRUE));
#endif

    if ((lchip != drv_vchip_get_pp_base(lchip)))
    {
        (p_usw_chip_master)[lchip] = (p_usw_chip_master)[drv_vchip_get_pp_base(lchip)];
    }
    else
    {
        p_usw_chip_master[lchip] = (sys_chip_master_t*)mem_malloc(MEM_SYSTEM_MODULE, sizeof(sys_chip_master_t));

        if (NULL == p_usw_chip_master[lchip])
        {
            SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
            return CTC_E_NO_MEMORY;
        }

        sal_memset(p_usw_chip_master[lchip], 0, sizeof(sys_chip_master_t));

        /* create mutex for chip module */
        ret = sal_mutex_create(&(p_usw_chip_master[lchip]->p_chip_mutex));
        if (ret || (!p_usw_chip_master[lchip]->p_chip_mutex))
        {
            ret = CTC_E_NO_MEMORY;
            goto error1;
        }
    }

    g_ldev_num = lchip_num;

    /*
        drv-io ,which inits in datapath, depends drv-init
    */
    ret = drv_init(lchip, 0);
    if (ret < 0)
    {
        ret = CTC_E_INIT_FAIL;
        goto error0;
    }

#if (0 == SDK_WORK_PLATFORM)
    {
        ctc_chip_device_info_t dev_info;
        sal_memset(&dev_info, 0, sizeof(ctc_chip_device_info_t));
        sys_usw_chip_get_device_info(lchip, &dev_info);
        if ((dev_info.version_id < 3) && DRV_IS_TSINGMA(lchip) && !dal_get_soc_active(lchip))
        {
            SupCtlReserved_m sup_rsv;
            uint32 cmd = DRV_IOR(SupCtlReserved_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, &sup_rsv);
            if(0 == GetSupCtlReserved(V, reserved_f, &sup_rsv))
            {
                drv_chip_pci_intf_adjust_en(lchip, 1);
                SetSupCtlReserved(V, reserved_f, &sup_rsv, 1);
                cmd = DRV_IOW(SupCtlReserved_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, &sup_rsv);
            }
        }

        if (DRV_FROM_TMM(lchip))
        {
            p_usw_chip_master[lchip]->sub_version = (dev_info.version_id != 1)?((dev_info.version_id == 2)?SYS_CHIP_SUB_VERSION_B:SYS_CHIP_SUB_VERSION_C):SYS_CHIP_SUB_VERSION_A;
        }
        else
        {
            p_usw_chip_master[lchip]->sub_version = (dev_info.version_id < 3)? SYS_CHIP_SUB_VERSION_A : SYS_CHIP_SUB_VERSION_B;
        }
    }
#else
    if (DRV_FROM_TM(lchip))
    {
        p_usw_chip_master[lchip]->sub_version = SYS_CHIP_SUB_VERSION_B;
    }
#endif

    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        drv_set_warmboot_status(lchip, CTC_WB_STATUS_RELOADING);
    }
    CTC_ERROR_GOTO(sys_usw_mchip_init(lchip), ret, error0);
    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_CHIP, _sys_usw_chip_dump_db), ret, error0);
    CTC_ERROR_GOTO(sys_usw_common_init(lchip), ret, error0);

    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_CHIP);
    return ret;
error0:
    sal_mutex_destroy(p_usw_chip_master[lchip]->p_chip_mutex);
error1:
    mem_free(p_usw_chip_master[lchip]);

    return ret;
}

int32
sys_usw_chip_check_task_done(uint8 lchip)
{
    uint8 temp_lchip=0;
    uint8 lchip_base = SYS_PP_BASE(lchip);

    temp_lchip =lchip_base + ((lchip - lchip_base) / PP_NUM_PER_CORE) * PP_NUM_PER_CORE;

    sys_usw_dma_free_task(lchip);
    sys_usw_dma_free_task(temp_lchip);
    sys_usw_dtel_free_task(lchip);
    sys_usw_interrupt_free_task(lchip);

#if defined SDK_IN_USERMODE
    ctc_sal_wait_all_task_done(lchip);
#endif

    return CTC_E_NONE;
}

int32
sys_usw_chip_deinit(uint8 lchip)
{
    uint32 cmd = 0;
    SupIntrCtl_m intr_ctl;

#ifdef _SAL_LINUX_UM
    if (CTC_WB_ENABLE(lchip))
    {
        dal_knet_set_wb_reloading(lchip, 1);
    }
#endif

    sys_usw_register_wb_sync_timer_en(lchip, FALSE);
    sys_usw_register_wb_sync_all(lchip);
    sys_usw_chip_set_active(lchip, FALSE);


    /* during warmboot, the failover must close */
    sys_usw_global_failover_en(lchip, FALSE);

    cmd = DRV_IOR(SupIntrCtl_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &intr_ctl);
    SetSupIntrCtl(V, funcIntrEn_f, &intr_ctl, 0);
    SetSupIntrCtl(V, interruptEn_f, &intr_ctl, 0);
    SetSupIntrCtl(V, padIntrEn_f, &intr_ctl, 0);
    SetSupIntrCtl(V, pcie0IntrEn_f, &intr_ctl, 0);
    SetSupIntrCtl(V, pcieIntrEn_f, &intr_ctl, 0);
    cmd = DRV_IOW(SupIntrCtl_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &intr_ctl);

    if (!SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        SYS_CB(SYS_CB_QOS_FCDL_SET_RECOVER_TIMER, lchip, FALSE);
    }
    sys_usw_chip_check_task_done(lchip);

    if (!p_usw_chip_master[lchip])
    {
        return CTC_E_NONE;
    }

#if 0
    {
        ctc_chip_device_info_t dev_info;
        sal_memset(&dev_info, 0, sizeof(ctc_chip_device_info_t));
        sys_usw_chip_get_device_info(lchip, &dev_info);
        if ((dev_info.version_id < 3) && DRV_IS_TSINGMA(lchip) && !dal_get_soc_active(lchip))
        {
            SupCtlReserved_m sup_rsv;
            uint32 cmd = DRV_IOR(SupCtlReserved_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, &sup_rsv);
            if(1 == GetSupCtlReserved(V, reserved_f, &sup_rsv))
            {
                drv_chip_pci_intf_adjust_en(lchip, 0);
                SetSupCtlReserved(V, reserved_f, &sup_rsv, 0);
                cmd = DRV_IOW(SupCtlReserved_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, &sup_rsv);
            }
        }
    }
#endif

    sal_task_sleep(300);
    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        (p_usw_chip_master)[lchip] = NULL;
        return CTC_E_NONE;
    }
    else
    {
        sal_mutex_destroy(p_usw_chip_master[lchip]->p_chip_mutex);
        mem_free(p_usw_chip_master[lchip]);
    }

    return 0;
}

/**
 @brief The function is to get the local chip num
*/
uint8
sys_usw_get_local_chip_num(void)
{

    return g_ldev_num;
}

/**
 @brief The function is to set chip's global chip id
*/
int32
sys_usw_set_gchip_id(uint8 lchip, uint8 gchip_id)
{
    if (NULL == p_usw_chip_master[lchip])
    {
        SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not initialized \n");
			return CTC_E_NOT_INIT;

    }

    if (lchip >= g_lchip_num)
    {
        SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid Local chip id \n");
			return CTC_E_INVALID_CHIP_ID;

    }

    SYS_GLOBAL_CHIPID_CHECK(gchip_id);

    p_usw_chip_master[lchip]->g_chip_id = gchip_id;
    CTC_ERROR_RETURN(drv_set_gchip_id(lchip, gchip_id));

    return CTC_E_NONE;
}

/**
 @brief The function is to get chip's global chip id
*/
int32
sys_usw_get_gchip_id(uint8 lchip, uint8* gchip_id)
{
    if (NULL == p_usw_chip_master[lchip])
    {
        SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not initialized \n");
			return CTC_E_NOT_INIT;

    }

    CTC_PTR_VALID_CHECK(gchip_id);

    *gchip_id = p_usw_chip_master[lchip]->g_chip_id;

    return CTC_E_NONE;
}

/**
 @brief The function is to judge whether the chip is local
*/
bool
sys_usw_chip_is_local(uint8 lchip, uint8 gchip_id)
{
    bool ret        = FALSE;

    if ((NULL != p_usw_chip_master[lchip])
        && (p_usw_chip_master[lchip]->g_chip_id == gchip_id))
    {
        ret = TRUE;
    }

    return ret;
}

/* function that call sys_usw_get_local_chip_id needs to check return */
int32
sys_usw_get_local_chip_id(uint8 gchip_id, uint8* lchip_id)
{
    uint8 i = 0;
    uint8 is_find = 0;

    CTC_PTR_VALID_CHECK(lchip_id);

    if (CTC_LINKAGG_CHIPID == gchip_id)
    {
        return CTC_E_NONE;
    }

    /* different chips have same lchip num */
    for (i = 0; i < g_lchip_num; i++)
    {
        if ((NULL != p_usw_chip_master[i]) && p_usw_chip_master[i]->g_chip_id == gchip_id)
        {
            is_find = 1;
            break;
        }
    }

    if (is_find)
    {
        *lchip_id = i;
        return CTC_E_NONE;
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }
}


STATIC int32
_sys_usw_chip_set_eth_cpu_cfg_tmm(uint8 lchip, ctc_chip_cpu_port_t* p_cpu_port)
{
#if defined(TSINGMA_MX) || defined(TSINGMA_GX)
    uint32 cmd = 0;
    ds_t ds;
    hw_mac_addr_t hw_mac;
    uint32 value = 0;
    uint32 i = 0;
    uint8 gchip = 0;
    uint8 step = EpeCpuMacCtl_arrayB_1_macDa_f - EpeCpuMacCtl_arrayB_0_macDa_f;
    mac_addr_t mac_tmp;

    CTC_MAX_VALUE_CHECK(p_cpu_port->vlanid, CTC_MAX_VLAN_ID);
    if (CTC_GPORT_TYPE(p_cpu_port->gport) != CTC_GPORT_TYPE_CPU_MAC)
    {
        return CTC_E_INVALID_PARAM;
    }

    sal_memset(&ds, 0, sizeof(ds_t));
    cmd = DRV_IOR(EpeCpuMacCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memcpy(mac_tmp, p_cpu_port->cpu_mac_da, sizeof(mac_addr_t));
    for(i=0; i<8; i++)
    {
        mac_tmp[5] = i;
        SYS_USW_SET_HW_MAC(hw_mac, mac_tmp);
        CTC_ERROR_RETURN(drv_set_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_macDa_f + step*i, &ds, hw_mac));
        value = p_cpu_port->vlanid;
        CTC_ERROR_RETURN(drv_set_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_vlanTag_f + step*i, &ds, &value));
        value = p_cpu_port->cpu_mac_sa[5];
        CTC_ERROR_RETURN(drv_set_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayA_0_macSaLow_f + step*i, &ds, &value));
    }
    hw_mac[1] = p_cpu_port->cpu_mac_sa[0];
    hw_mac[0] = (p_cpu_port->cpu_mac_sa[1] << 24)|(p_cpu_port->cpu_mac_sa[2] << 16) | (p_cpu_port->cpu_mac_sa[3] << 8) | (p_cpu_port->cpu_mac_sa[4]);
    SetEpeCpuMacCtl(A, macSaHigh_f, &ds, hw_mac);
    SetEpeCpuMacCtl(V, tpid_f, &ds, p_cpu_port->tpid);
    cmd = DRV_IOW(EpeCpuMacCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    value = 0x55aa;
    cmd = DRV_IOW(CpuMacCtl_t, CpuMacCtl_etherType_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

    sys_usw_get_gchip_id(lchip, &gchip);
    for(i=0; i<4; i++)
    {
        p_cpu_port->cpu_mac_da[5] = i;
        value = CTC_MAP_LPORT_TO_GPORT(gchip, i) | (CTC_GPORT_TYPE_CPU_MAC << CTC_TYPE_PORT_OFFSET);
        sys_usw_packet_set_cpu_mac(lchip, i, value, p_cpu_port->cpu_mac_da, p_cpu_port->cpu_mac_sa, p_cpu_port->vlanid, p_cpu_port->tpid);
    }
#endif
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_chip_get_eth_cpu_cfg_tmm(uint8 lchip, ctc_chip_cpu_port_t* p_cpu_port)
{
#if defined(TSINGMA_MX) || defined(TSINGMA_GX)
    uint32 cmd = 0;
    ds_t ds;
    hw_mac_addr_t hw_mac;
    uint8 cpu_mac_id = 0;
    uint32 value = 0;

    cpu_mac_id = (p_cpu_port->gport)&0x3;

    sal_memset(&ds, 0, sizeof(ds_t));
    cmd = DRV_IOR(EpeCpuMacCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    CTC_ERROR_RETURN(drv_get_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_macDa_f, &ds, hw_mac));
    SYS_USW_SET_USER_MAC(p_cpu_port->cpu_mac_da, hw_mac);
    p_cpu_port->cpu_mac_da[5] = cpu_mac_id & 0xFF;
    CTC_ERROR_RETURN(drv_get_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_vlanTag_f, &ds, &value));
    p_cpu_port->vlanid = value & 0xFFFF;

    GetEpeCpuMacCtl(A, macSa_f, &ds, hw_mac);
    SYS_USW_SET_USER_MAC(p_cpu_port->cpu_mac_sa, hw_mac);
    p_cpu_port->tpid = GetEpeCpuMacCtl(V, tpid_f, &ds);

    CTC_ERROR_RETURN(drv_get_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayA_0_macSaLow_f + cpu_mac_id, &ds, &value));
    p_cpu_port->cpu_mac_sa[5] = value & 0xFF;
    GetEpeCpuMacCtl(A, macSaHigh_f, &ds, hw_mac);
    p_cpu_port->cpu_mac_sa[0] = hw_mac[1];
    p_cpu_port->cpu_mac_sa[1] = hw_mac[0] >> 24;
    p_cpu_port->cpu_mac_sa[2] = (hw_mac[0] >> 16) & 0xFF;
    p_cpu_port->cpu_mac_sa[3] = (hw_mac[0] >> 8) & 0xFF;
    p_cpu_port->cpu_mac_sa[4] = hw_mac[0] & 0xFF;
    p_cpu_port->tpid = GetEpeCpuMacCtl(V, tpid_f, &ds);
#endif
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_chip_set_eth_cpu_cfg_at(uint8 lchip, ctc_chip_cpu_port_t* p_cpu_port)
{
#if defined(ARCTIC)
    uint32 cmd = 0;
    ds_t ds;
    hw_mac_addr_t hw_mac;
    uint32 value = 0;
    uint32 i = 0;
    uint8 eth_en = 1;
    uint8 gchip = 0;
    uint8 pp_id = 0;
    uint8 core_pp_num = SYS_CORE_PP_NUM(lchip);
    mac_addr_t mac_tmp;
    uint8 step = EpeCpuMacCtl_arrayB_1_macDa_f - EpeCpuMacCtl_arrayB_0_macDa_f;

    CTC_MAX_VALUE_CHECK(p_cpu_port->vlanid, CTC_MAX_VLAN_ID);
    if (CTC_GPORT_TYPE(p_cpu_port->gport) != CTC_GPORT_TYPE_CPU_MAC)
    {
        return CTC_E_INVALID_PARAM;
    }

    sal_memset(&ds, 0, sizeof(ds_t));
    cmd = DRV_IOR(EpeCpuMacCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    if(0 == p_cpu_port->cpu_mac_da[0]
        && 0 == p_cpu_port->cpu_mac_da[1]
        && 0 == p_cpu_port->cpu_mac_da[2]
        && 0 == p_cpu_port->cpu_mac_da[3]
        && 0 == p_cpu_port->cpu_mac_da[4])
    {
        eth_en = 0;
    }
    sal_memcpy(mac_tmp, p_cpu_port->cpu_mac_da, sizeof(mac_addr_t));
    for(i=0; i<8; i++)
    {
        mac_tmp[5] = 0+i;
        SYS_USW_SET_HW_MAC(hw_mac, mac_tmp);
        CTC_ERROR_RETURN(drv_set_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_macDa_f + step*i, &ds, hw_mac));
        value = p_cpu_port->vlanid;
        CTC_ERROR_RETURN(drv_set_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_vlanTag_f + step*i, &ds, &value));
        value = eth_en;
        CTC_ERROR_RETURN(drv_set_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_ethEn_f + step*i, &ds, &value));
    }

    SYS_USW_SET_HW_MAC(hw_mac, p_cpu_port->cpu_mac_sa);
    SetEpeCpuMacCtl(A, macSa_f, &ds, hw_mac);
    SetEpeCpuMacCtl(V, etherType_f, &ds, 0x55aa);
    SetEpeCpuMacCtl(V, tpid_f, &ds, p_cpu_port->tpid);
    cmd = DRV_IOW(EpeCpuMacCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    sal_memset(&ds, 0, sizeof(ds_t));
    SetNetRxCpuMacCtl(A, macAddr_f, &ds, hw_mac);
    SetNetRxCpuMacCtl(V, macCheckEn_f, &ds, eth_en);
    for (pp_id = 0; pp_id < SYS_PP_NUM(lchip); pp_id++)
    {
        /*core0 pp0 pp1 & core1 pp0 pp1 dp 1 sub_channel 24 for cpumac need config*/
        if (0 == (pp_id%core_pp_num) || 1 == (pp_id%core_pp_num))
        {
            lchip = SYS_PP_BASE(lchip) + pp_id;
            cmd = DRV_IOW(NetRxCpuMacCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, 1), &ds));
        }
    }

    sal_memset(&ds, 0, sizeof(ds_t));
    for (pp_id = 0; pp_id < SYS_PP_NUM(lchip); pp_id++)
    {
        /*core0 pp0 pp1 & core1 pp0 pp1 dp 1 sub_channel 24 for cpumac need config*/
        if (0 == (pp_id%core_pp_num) || 1 == (pp_id%core_pp_num))
        {
            lchip = SYS_PP_BASE(lchip) + pp_id;
            /*pause frame length could >=64*/
            cmd = DRV_IOR(NetRxCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, 1), &ds));
            SetNetRxCtl(V, cfgMiscRemoveCpuHdrEn_f, &ds, eth_en);
            cmd = DRV_IOW(NetRxCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_DP_EN(cmd, 1), &ds));
        }
    }

    sys_usw_get_gchip_id(lchip, &gchip);
    for(i=0; i<4; i++)
    {
        p_cpu_port->cpu_mac_da[5] = i;
        value = CTC_MAP_LPORT_TO_GPORT(gchip, i) | (CTC_GPORT_TYPE_CPU_MAC << CTC_TYPE_PORT_OFFSET);
        sys_usw_packet_set_cpu_mac(lchip, i, value, p_cpu_port->cpu_mac_da, p_cpu_port->cpu_mac_sa, p_cpu_port->vlanid, p_cpu_port->tpid);
    }
#endif
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_chip_get_eth_cpu_cfg_at(uint8 lchip, ctc_chip_cpu_port_t* p_cpu_port)
{
#if defined(ARCTIC)
    uint8 cpu_mac_id = 0;
    uint32 cmd = 0;
    ds_t ds;
    hw_mac_addr_t hw_mac;
    uint32 value = 0;

    cpu_mac_id = (p_cpu_port->gport)&0x3;

    sal_memset(&ds, 0, sizeof(ds_t));
    cmd = DRV_IOR(EpeCpuMacCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    CTC_ERROR_RETURN(drv_get_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_macDa_f, &ds, hw_mac));
    SYS_USW_SET_USER_MAC(p_cpu_port->cpu_mac_da, hw_mac);
    p_cpu_port->cpu_mac_da[5] = cpu_mac_id;
    CTC_ERROR_RETURN(drv_get_field(lchip, EpeCpuMacCtl_t, EpeCpuMacCtl_arrayB_0_vlanTag_f, &ds, &value));
    p_cpu_port->vlanid = value & 0xFFFF;
    GetEpeCpuMacCtl(A, macSa_f, &ds, hw_mac);
    SYS_USW_SET_USER_MAC(p_cpu_port->cpu_mac_sa, hw_mac);
    p_cpu_port->tpid = GetEpeCpuMacCtl(V, tpid_f, &ds);
#endif
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_chip_get_eth_cpu_cfg(uint8 lchip, ctc_chip_cpu_port_t* p_cpu_port)
{
    uint8 gchip_id = SYS_MAP_CTC_GPORT_TO_GCHIP(p_cpu_port->gport);

    if (!DRV_FROM_TMM(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if (CTC_GPORT_TYPE(p_cpu_port->gport) != CTC_GPORT_TYPE_CPU_MAC)
    {
        return CTC_E_INVALID_PARAM;
    }
    if (!sys_usw_chip_is_local(lchip, gchip_id))
    {
        return CTC_E_INVALID_CONFIG;
    }

    if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {

        CTC_ERROR_RETURN(_sys_usw_chip_get_eth_cpu_cfg_tmm(lchip, p_cpu_port));
    }
    else if(DRV_IS_AT(lchip))
    {
        CTC_ERROR_RETURN(_sys_usw_chip_get_eth_cpu_cfg_at(lchip, p_cpu_port));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_chip_set_eth_cpu_cfg(uint8 lchip, ctc_chip_cpu_port_t* p_cpu_port)
{
    uint32 cmd = 0;
    uint32 chan_id = 0;
    uint8 lchan_id = 0;
    uint8 slice_id = 0;
    uint32 tocpu_bmp[4] = {0};
    ds1_t ds;
    hw_mac_addr_t hw_mac_da;
    hw_mac_addr_t hw_mac_sa;
    IpeHeaderAdjustCtl_m ipe_header_adjust_ctl;
    EpeNextHopCtl_m epe_nhop_ctl;
    uint32 field_value = 0;
    uint8 gchip_id = SYS_MAP_CTC_GPORT_TO_GCHIP(p_cpu_port->gport);
    uint8 idx = 0xFF;
    uint16 lport;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    BufferStoreCtl_m buf_stro_ctl;
    DsQMgrNetShpPpsCfg_m net_shp_pps;


    CTC_VLAN_RANGE_CHECK(p_cpu_port->vlanid);

    dmps_port_info.gport = p_cpu_port->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (!sys_usw_chip_is_local(lchip, gchip_id))
    {
        return CTC_E_INVALID_CONFIG;
    }

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        CTC_ERROR_RETURN(_sys_usw_chip_set_eth_cpu_cfg_tmm(lchip, p_cpu_port));
        return CTC_E_NONE;
    }
    else if (DRV_FROM_AT(lchip))
    {
        CTC_ERROR_RETURN(_sys_usw_chip_set_eth_cpu_cfg_at(lchip, p_cpu_port));
        return CTC_E_NONE;
    }

    if(!SYS_IS_NETWORK_CHANNEL(chan_id))
    {
        return CTC_E_INVALID_PARAM;
    }
    cmd = DRV_IOR(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &buf_stro_ctl));
    if(0 == GetBufferStoreCtl(V, cpuRxPortModeEn_f, &buf_stro_ctl))
    {
        idx = 0;
        lport = CTC_MAP_GPORT_TO_LPORT(p_cpu_port->gport);
        SetBufferStoreCtl(V, g0_0_cpuPort_f, &buf_stro_ctl, lport);
        SetBufferStoreCtl(V, g0_1_cpuPort_f, &buf_stro_ctl, lport);
        SetBufferStoreCtl(V, g0_2_cpuPort_f, &buf_stro_ctl, lport);
        SetBufferStoreCtl(V, g0_3_cpuPort_f, &buf_stro_ctl, lport);
        SetBufferStoreCtl(V, cpuRxPortModeEn_f, &buf_stro_ctl,1);
    }
    else
    {
        uint8 loop;
        lport = GetBufferStoreCtl(V, g0_0_cpuPort_f, &buf_stro_ctl);
        for(loop=0; loop < 4; loop++)
        {
            if(CTC_MAP_GPORT_TO_LPORT(p_cpu_port->gport) == GetBufferStoreCtl(V, g0_0_cpuPort_f+loop, &buf_stro_ctl))
            {
                idx = loop;
                break;
            }
            else if(0 != loop && GetBufferStoreCtl(V, g0_0_cpuPort_f+loop, &buf_stro_ctl) == lport)
            {
                idx = loop;
                SetBufferStoreCtl(V, g0_0_cpuPort_f+loop, &buf_stro_ctl, CTC_MAP_GPORT_TO_LPORT(p_cpu_port->gport));
                break;
            }
        }
        if(idx == 0xFF)
        {
            return CTC_E_NO_RESOURCE;
        }
    }
    cmd = DRV_IOW(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &buf_stro_ctl));
    /*Needn't error return, because in the init phase the packet module still not init*/
    sys_usw_packet_set_cpu_mac(lchip, idx, p_cpu_port->gport, p_cpu_port->cpu_mac_da, p_cpu_port->cpu_mac_sa, p_cpu_port->vlanid, p_cpu_port->tpid);

    field_value = chan_id;
    cmd = DRV_IOW(BufferStoreCpuRxLogChannelMap_t,BufferStoreCpuRxLogChannelMap_g_0_cpuChanId_f+idx);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip,0,cmd,&field_value));

    slice_id = SYS_MAP_CHANID_TO_SLICE(chan_id);
    lchan_id = chan_id&0x3F;

    sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(IpeHeaderAdjustCpuChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, slice_id, cmd, &ds));
    GetIpeHeaderAdjustCpuChanCtl(A, fromCpuEn_f, &ds, tocpu_bmp);
    CTC_BIT_SET(tocpu_bmp[lchan_id >> 5], (lchan_id&0x1F));
    SetIpeHeaderAdjustCpuChanCtl(A, fromCpuEn_f, &ds, tocpu_bmp);
    cmd = DRV_IOW(IpeHeaderAdjustCpuChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, slice_id, cmd, &ds));

    sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(IpeFwdCpuChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, slice_id, cmd, &ds));
    SetIpeFwdCpuChanCtl(A, fromCpuEn_f, &ds, tocpu_bmp);
    cmd = DRV_IOW(IpeFwdCpuChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, slice_id, cmd, &ds));

    sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(EpeHeaderEditCpuChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, slice_id, cmd, &ds));
    SetEpeHeaderEditCpuChanCtl(A, toCpuEn_f, &ds, tocpu_bmp);
    cmd = DRV_IOW(EpeHeaderEditCpuChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, slice_id, cmd, &ds));

    sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(EpeHdrAdjustChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, slice_id, cmd, &ds));
    SetEpeHdrAdjustChanCtl(A, toCpuEn_f, &ds, tocpu_bmp);
    cmd = DRV_IOW(EpeHdrAdjustChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, slice_id, cmd, &ds));

    sal_memset(tocpu_bmp, 0, sizeof(tocpu_bmp));
    sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    GetBufferStoreCtl(A, fromCpuEn_f, &ds, tocpu_bmp);
    CTC_BIT_SET(tocpu_bmp[chan_id >> 5], (chan_id&0x1F));
    SetBufferStoreCtl(A, fromCpuEn_f, &ds, tocpu_bmp);
    cmd = DRV_IOW(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    SYS_USW_SET_HW_MAC(hw_mac_da, p_cpu_port->cpu_mac_da);
    SYS_USW_SET_HW_MAC(hw_mac_sa, p_cpu_port->cpu_mac_sa);

    sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(DsPacketHeaderEditTunnel_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &ds));
    SetDsPacketHeaderEditTunnel(A, macSa_f, &ds, hw_mac_sa);
    SetDsPacketHeaderEditTunnel(V, packetHeaderL2En_f, &ds, 1);
    SetDsPacketHeaderEditTunnel(V, vlanIdValid_f, &ds, 1);
    SetDsPacketHeaderEditTunnel(V, vlanId_f, &ds, p_cpu_port->vlanid);
    SetDsPacketHeaderEditTunnel(A, macDa_f, &ds, hw_mac_da);
    cmd = DRV_IOW(DsPacketHeaderEditTunnel_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &ds));

    field_value = p_cpu_port->tpid;
    cmd = DRV_IOW(EpePktHdrCtl_t, EpePktHdrCtl_tpid_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    field_value = 0x55aa;
    cmd = DRV_IOW(EpePktHdrCtl_t, EpePktHdrCtl_headerEtherType_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

#if 0
    field_value = 47;
    cmd = DRV_IOW(BufRetrvChanIdCfg_t, BufRetrvChanIdCfg_cfgCpuChanId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
#endif


    field_value = DRV_ENUM(DRV_STK_MUX_TYPE_HDR_WITH_L2);
    cmd = DRV_IOW(IpePhyPortMuxCtl_t, IpePhyPortMuxCtl_muxType_f );
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_value));

    sal_memset(&ipe_header_adjust_ctl, 0, sizeof(ipe_header_adjust_ctl));
    cmd = DRV_IOR(IpeHeaderAdjustCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipe_header_adjust_ctl));
    SetIpeHeaderAdjustCtl(V, headerMacDaCheckEn_f, &ipe_header_adjust_ctl,0);
    SetIpeHeaderAdjustCtl(V, headerTpid_f, &ipe_header_adjust_ctl, p_cpu_port->tpid);
    SetIpeHeaderAdjustCtl(V, headerEtherTypeCheckDisable_f, &ipe_header_adjust_ctl, 1);
    SetIpeHeaderAdjustCtl(V, headerEtherType_f, &ipe_header_adjust_ctl,0x55aa);
    SetIpeHeaderAdjustCtl(V, packetHeaderBypassAll_f, &ipe_header_adjust_ctl,1);
    SetIpeHeaderAdjustCtl(V, fromCpuBypassAll_f , &ipe_header_adjust_ctl,1);
    cmd = DRV_IOW(IpeHeaderAdjustCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ipe_header_adjust_ctl));

    sal_memset(&epe_nhop_ctl, 0, sizeof(epe_nhop_ctl));
    cmd = DRV_IOR(EpeNextHopCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_nhop_ctl));
    SetEpeNextHopCtl(V, toCpuPktDoNotBypassNhp_f, &epe_nhop_ctl, 1);
    cmd = DRV_IOW(EpeNextHopCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_nhop_ctl));

    /*fwd iloop cpu enable*/
    field_value = 1;
    cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_fromCpuIloopEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    sys_usw_get_gchip_id(lchip, &gchip_id);
    field_value = SYS_ENCODE_DESTMAP(gchip_id, SYS_RSV_PORT_ILOOP_ID);
    cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_fromCpuIloopDestMap_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    field_value = SYS_RSV_PORT_OAM_CPU_ID;
    cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_fromCpuIloopLocalPhyPort_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    field_value = 1;
    sal_memset(&net_shp_pps, 0, sizeof(DsQMgrNetShpPpsCfg_m));
    SetDsQMgrNetShpPpsCfg(V, ppsMode_f, &net_shp_pps, field_value);
    SetDsQMgrNetShpPpsCfg(V, ppsShift_f, &net_shp_pps, MCHIP_CAP(SYS_CAP_QOS_SHP_PPS_SHIFT));
    cmd = DRV_IOW(DsQMgrNetShpPpsCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &net_shp_pps));

    return CTC_E_NONE;
}

int32 sys_usw_chip_set_eth_cpu_cfg(uint8 lchip)
{
    ctc_chip_cpu_port_t cpu_port;
    uint8  gchip;

    sal_memcpy(&cpu_port.cpu_mac_sa, &p_usw_chip_master[lchip]->cpu_mac_sa, sizeof(mac_addr_t));
    sys_usw_get_gchip_id(lchip, &gchip);
    cpu_port.gport = CTC_MAP_LPORT_TO_GPORT(gchip,  p_usw_chip_master[lchip]->cpu_lport);
    sal_memcpy(&cpu_port.cpu_mac_da, &p_usw_chip_master[lchip]->cpu_mac_da[0], sizeof(mac_addr_t));
    cpu_port.tpid = p_usw_chip_master[lchip]->tpid;
    cpu_port.vlanid = p_usw_chip_master[lchip]->vlan_id;

    return _sys_usw_chip_set_eth_cpu_cfg(lchip, &cpu_port);
}

int32
_sys_usw_chip_set_feature_init(uint8 lchip, uint64 feature_en)
{
    uint32 feature_en_bmp[2] = {0};
    uint8 loop = 0;

    feature_en_bmp[0] = feature_en & 0xFFFFFFFF;
    feature_en_bmp[1] = (feature_en >> 32) & 0xFFFFFFFF;
    for (loop = 0; loop < CTC_FEATURE_MAX; loop++)
    {
        if (CTC_BMP_ISSET(feature_en_bmp, loop) && CTC_IS_BIT_SET(p_sys_mchip_master[lchip]->feature[loop], SYS_FEATURE_CAP))
        {
            CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[loop], SYS_FEATURE_INIT);
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_chip_set_feature_pp_init(uint8 lchip, uint64* feature_en)
{
    uint8 loop = 0;
    uint16 features[] = {
        CTC_FEATURE_ACL, CTC_FEATURE_SCL, CTC_FEATURE_IPUC, CTC_FEATURE_L3IF,CTC_FEATURE_OAM
    };
    for (loop = 0; loop < sizeof(features)/sizeof(uint16); loop++)
    {
        if(*feature_en & (1ULL << features[loop]) && MCHIP_FEATURE_CAP(lchip, features[loop]))
        {
            CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[features[loop]], SYS_FEATURE_PP_EN);
        }
    }
    if (*feature_en & (1ULL << CTC_FEATURE_SCL))
    {
        CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_SRV6         ], SYS_FEATURE_PP_EN);
        CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_VLAN_MAPPING ], SYS_FEATURE_PP_EN);
        CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_OVERLAY      ], SYS_FEATURE_PP_EN);
        CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_SECURITY     ], SYS_FEATURE_PP_EN);
    }
    if((*feature_en & (1ULL << CTC_FEATURE_IPUC)))
    {
        CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_TRILL    ], SYS_FEATURE_PP_EN);
        CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_FCOE     ], SYS_FEATURE_PP_EN);
        CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_IPMC     ], SYS_FEATURE_PP_EN);
        CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_IP_TUNNEL    ], SYS_FEATURE_PP_EN);
    }
    CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_IPFIX    ], SYS_FEATURE_PP_EN);
    CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_STATS    ], SYS_FEATURE_PP_EN);
    CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_QOS      ], SYS_FEATURE_PP_EN);
    CTC_BIT_SET(p_sys_mchip_master[lchip]->feature[CTC_FEATURE_DOT1AE   ], SYS_FEATURE_PP_EN);
    return CTC_E_NONE;
}

/**
 @brief The function is to set chip's global cfg
*/
int32
sys_usw_set_chip_global_cfg(uint8 lchip, ctc_chip_global_cfg_t* chip_cfg)
{
    uint8 gchip = 0;
    uint8 loop = 0, loop2 = 0;
    ctc_port_bitmap_t zeros = {0};
    uint16 index = 0;

    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(chip_cfg);

    if (!CTC_WB_ENABLE(lchip))
    {
        drv_set_warmboot_status(lchip, chip_cfg->io_wr_dis?CTC_WB_STATUS_RELOADING:CTC_WB_STATUS_DONE);
    }

    gchip = SYS_MAP_CTC_GPORT_TO_GCHIP(chip_cfg->cpu_port);
    if (chip_cfg->cpu_port_en && !sys_usw_chip_is_local(lchip, gchip) && !DRV_FROM_TMM(lchip))
    {
         return CTC_E_INVALID_PORT;
    }
    p_usw_chip_master[lchip]->cut_through_en       = chip_cfg->cut_through_en;

    _sys_usw_chip_set_feature_init(lchip, chip_cfg->feature_en);

    if (DRV_FROM_AT(lchip))
    {
        _sys_usw_chip_set_feature_pp_init(lchip, &chip_cfg->feature_pp_en);
    }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_ACL))
   {
       for (index = 0; index < sizeof(acl_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, acl_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_SCL))
   {
       for (index = 0; index < sizeof(scl_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, scl_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_MPLS))
   {
       for (index = 0; index < sizeof(mpls_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, mpls_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_L3IF))
   {
       for (index = 0; index < sizeof(l3if_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, l3if_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_IPUC))
   {
       for (index = 0; index < sizeof(ipuc_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, ipuc_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_IPFIX))
   {
       for (index = 0; index < sizeof(ipfix_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, ipfix_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_QOS))
   {
       for (index = 0; index < sizeof(qos_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, qos_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_OAM))
   {
       for (index = 0; index < sizeof(oam_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, oam_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
   if (MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_STATS))
   {
       for (index = 0; index < sizeof(stats_feature_mode_tbl)/sizeof(uint16); index++)
       {
           drv_sdb_set_tbl_feature_mode(lchip, stats_feature_mode_tbl[index], DRV_FEATURE_MODE_PER_PP);
       }
   }
#ifndef EMULATION_ENV
   if (chip_cfg->sdb_en)
#endif
   {
       CTC_ERROR_RETURN(_sys_usw_chip_init_ser(lchip, chip_cfg));
   }

   /*support cut through speed*/
    p_usw_chip_master[lchip]->cut_through_speed[0].port_speed = CTC_PORT_SPEED_1G;
    p_usw_chip_master[lchip]->cut_through_speed[1].port_speed = CTC_PORT_SPEED_2G5;
    p_usw_chip_master[lchip]->cut_through_speed[2].port_speed = CTC_PORT_SPEED_5G;
    p_usw_chip_master[lchip]->cut_through_speed[3].port_speed = CTC_PORT_SPEED_10G;
    p_usw_chip_master[lchip]->cut_through_speed[4].port_speed = CTC_PORT_SPEED_20G;
    p_usw_chip_master[lchip]->cut_through_speed[5].port_speed = CTC_PORT_SPEED_25G;
    p_usw_chip_master[lchip]->cut_through_speed[6].port_speed = CTC_PORT_SPEED_40G;
    p_usw_chip_master[lchip]->cut_through_speed[7].port_speed = CTC_PORT_SPEED_50G;
    p_usw_chip_master[lchip]->cut_through_speed[8].port_speed = CTC_PORT_SPEED_100G;
    p_usw_chip_master[lchip]->cut_through_speed[9].port_speed = CTC_PORT_SPEED_200G;
    p_usw_chip_master[lchip]->cut_through_speed[10].port_speed = CTC_PORT_SPEED_400G;
    p_usw_chip_master[lchip]->cut_through_speed[11].port_speed = CTC_PORT_SPEED_800G;

    /**<
      [GG] 1:10/40/100G mixed;2:1/10/100G mixed 3:1/10/40G mixed, else none */

    if(chip_cfg->cut_through_speed == 1)
    {
       p_usw_chip_master[lchip]->cut_through_speed[3].enable = 1;
       p_usw_chip_master[lchip]->cut_through_speed[6].enable = 1;
       p_usw_chip_master[lchip]->cut_through_speed[8].enable = 1;
    }
    else if(chip_cfg->cut_through_speed == 2)
    {
       p_usw_chip_master[lchip]->cut_through_speed[0].enable = 1;
       p_usw_chip_master[lchip]->cut_through_speed[3].enable = 1;
       p_usw_chip_master[lchip]->cut_through_speed[8].enable = 1;
    }
    else if(chip_cfg->cut_through_speed == 3)
    {
        p_usw_chip_master[lchip]->cut_through_speed[0].enable = 1;
        p_usw_chip_master[lchip]->cut_through_speed[3].enable = 1;
        p_usw_chip_master[lchip]->cut_through_speed[6].enable = 1;
    }

    if(chip_cfg->cut_through_speed_bitmap !=0)
     {
        for(loop =0 ; loop < CTC_PORT_SPEED_MAX;loop++)
        {
          if(!CTC_IS_BIT_SET(chip_cfg->cut_through_speed_bitmap,loop)
            || (loop == CTC_PORT_SPEED_10M) || (loop == CTC_PORT_SPEED_100M))
          {
            continue;
          }
          for(loop2 =0 ; loop2 < CTC_PORT_SPEED_MAX;loop2++)
          {
            if(p_usw_chip_master[lchip]->cut_through_speed[loop2].port_speed == loop)
            {
              p_usw_chip_master[lchip]->cut_through_speed[loop2].enable = 1;
              break;
            }
          }
        }
     }

    /*CPU PORT*/
    if (!DRV_FROM_TMM(lchip))
    {
        p_usw_chip_master[lchip]->cpu_eth_en = chip_cfg->cpu_port_en;
        p_usw_chip_master[lchip]->cpu_lport = CTC_MAP_GPORT_TO_LPORT(chip_cfg->cpu_port) ;
        p_usw_chip_master[lchip]->tpid = chip_cfg->tpid;
        if ((chip_cfg->vlanid) > CTC_MAX_VLAN_ID)
        {
            return CTC_E_INVALID_PARAM;
        }
        p_usw_chip_master[lchip]->vlan_id = chip_cfg->vlanid;
        sal_memcpy(p_usw_chip_master[lchip]->cpu_mac_sa, chip_cfg->cpu_mac_sa, sizeof(mac_addr_t));
        sal_memcpy(p_usw_chip_master[lchip]->cpu_mac_da, chip_cfg->cpu_mac_da, sizeof(mac_addr_t)*SYS_USW_CPU_MAC_NUM);
    }

    p_usw_chip_master[lchip]->alpm_affinity_mask = chip_cfg->alpm_affinity_mask;
    p_usw_chip_master[lchip]->normal_affinity_mask = chip_cfg->normal_affinity_mask;

    if(0 == sal_memcmp(chip_cfg->fwd_pbm, zeros, sizeof(ctc_port_bitmap_t)))
    {
        sal_memset(p_usw_chip_master[lchip]->fwd_pbm, 0xff, sizeof(ctc_port_bitmap_t));
    }
    else
    {
        sal_memcpy(p_usw_chip_master[lchip]->fwd_pbm, chip_cfg->fwd_pbm, sizeof(ctc_port_bitmap_t));
        CTC_BMP_SET_RANGE(p_usw_chip_master[lchip]->fwd_pbm, SYS_RSV_PORT_START, (SYS_RSV_PORT_END - SYS_RSV_PORT_START + 1) );
    }

    return CTC_E_NONE;
}

uint8
sys_usw_chip_get_fwd_port_en(uint8 lchip, uint16 lport)
{
    if (!p_usw_chip_master[lchip])
    {
        return 0;
    }
    return CTC_BMP_ISSET(p_usw_chip_master[lchip]->fwd_pbm, lport) ? 1 : 0;
}

uint32 *
sys_usw_chip_get_fwd_pbm(uint8 lchip)
{
    if (!p_usw_chip_master[lchip])
    {
        return 0;
    }
    return p_usw_chip_master[lchip]->fwd_pbm;
}

uint64
sys_usw_chip_get_affinity(uint8 lchip, uint8 is_alpm)
{
    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    return is_alpm ? p_usw_chip_master[lchip]->alpm_affinity_mask : p_usw_chip_master[lchip]->normal_affinity_mask;
}

int32
sys_usw_get_chip_clock(uint8 lchip, uint16* freq)
{
    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    *freq = sys_usw_get_core_freq(lchip, 0);

    return CTC_E_NONE;
}

int32
sys_usw_get_chip_cpumac(uint8 lchip, uint8* mac_sa, uint8* mac_da)
{
    sal_memcpy(mac_sa, p_usw_chip_master[lchip]->cpu_mac_sa, sizeof(mac_addr_t));
    sal_memcpy(mac_da, p_usw_chip_master[lchip]->cpu_mac_da[0], sizeof(mac_addr_t));

    return CTC_E_NONE;
}

bool
sys_usw_chip_is_eth_cpu_port(uint8 lchip, uint16 lport)
{
    uint16 sys_port[4];
    BufferStoreCtl_m buf_stro_ctl;
    uint32 cmd = DRV_IOR(BufferStoreCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &buf_stro_ctl));
    if(GetBufferStoreCtl(V, cpuRxPortModeEn_f, &buf_stro_ctl))
    {
        sys_port[0] = GetBufferStoreCtl(V, g0_0_cpuPort_f, &buf_stro_ctl);
        sys_port[1] = GetBufferStoreCtl(V, g0_1_cpuPort_f, &buf_stro_ctl);
        sys_port[2] = GetBufferStoreCtl(V, g0_2_cpuPort_f, &buf_stro_ctl);
        sys_port[3] = GetBufferStoreCtl(V, g0_3_cpuPort_f, &buf_stro_ctl);
        if(lport == sys_port[0] || lport == sys_port[1] || lport == sys_port[2] || lport == sys_port[3])
        {
            return TRUE;
        }
        return FALSE;
    }
    else
    {
        return FALSE;
    }
}

int32
sys_usw_get_chip_cpu_eth_en(uint8 lchip, uint8 *enable, uint8* cpu_eth_chan)
{
    uint8 gchip = 0;
    uint32 chan_id = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    sys_usw_get_gchip_id(lchip, &gchip);
    *enable = p_usw_chip_master[lchip]->cpu_eth_en;
    dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip, p_usw_chip_master[lchip]->cpu_lport);
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    *cpu_eth_chan = chan_id;

    return ((*enable && chan_id==SYS_COMMON_USELESS_CHANNEL)? CTC_E_INTR_INVALID_PARAM : CTC_E_NONE);
}


#define __CUT_THROUGH__
uint8
sys_usw_chip_get_cut_through_en(uint8 lchip)
{
    return p_usw_chip_master[lchip]->cut_through_en ?1:0;
}

uint8
sys_usw_chip_get_cut_through_speed(uint8 lchip, uint32 gport)
{
    uint8  cut_through_speed = 0;
    uint8  found = 0;
    uint8  loop = 0;
    uint32 port_type = 0;
    uint32 speed_mode = 0;
    uint8  speed_cnt = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    if (!p_usw_chip_master[lchip]->cut_through_en)
    {
        return 0;
    }
    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SPEED_MODE, (void *)&speed_mode));
    if ((port_type != SYS_DMPS_NETWORK_PORT)&&(port_type != SYS_DMPS_CPUMAC_NETWORK_PORT ))
    {
        return 0;
    }

    for (loop = 0; loop < CTC_PORT_SPEED_MAX; loop++)
    {

        if ( p_usw_chip_master[lchip]->cut_through_speed[loop].enable)
        {
            cut_through_speed += 1;
        }
        if (p_usw_chip_master[lchip]->cut_through_speed[loop].enable &&
            (p_usw_chip_master[lchip]->cut_through_speed[loop].port_speed == speed_mode ))
        {
            found = 1;
            break;
        }
    }
    /*cut_through only support 7 speed*/
    speed_cnt = DRV_FROM_TM(lchip) ? 0xF : 7;
    return (found && cut_through_speed <= speed_cnt) ? cut_through_speed : 0;

}

#define __ECC_RECOVER__


int32
sys_usw_chip_get_reset_hw_en(uint8 lchip)
{

   uint32 hw_reset_en;

   drv_ser_get_cfg(lchip, DRV_SER_CFG_TYPE_HW_RESER_EN, &hw_reset_en);

   return hw_reset_en;
}

STATIC int32
_sys_usw_chip_init_ser(uint8 lchip, ctc_chip_global_cfg_t* p_cfg)
{
    drv_ser_global_cfg_t  ser_cfg;
    uint8 pp_id = 0;

    sal_memset(&ser_cfg,0,sizeof(ser_cfg));
    ser_cfg.ecc_recover_en     = p_cfg->ecc_recover_en;
    ser_cfg.tcam_scan_en       = p_cfg->tcam_scan_en;
    ser_cfg.sbe_scan_en        = p_cfg->tcam_scan_en;
    ser_cfg.sdb_en             = p_cfg->sdb_en;
    ser_cfg.sdb_type           = p_cfg->sdb_type;
    ser_cfg.mem_addr           = p_cfg->sdb_mem_addr;
    ser_cfg.mem_size           = p_cfg->sdb_mem_size;
    ser_cfg.tcam_scan_burst_entry_num = 4096;
    ser_cfg.tcam_scan_interval = 0; /* Not start tcam key scan thread when init */
    ser_cfg.sbe_scan_interval  = 0; /* Not start single bit error scan thread when init */
    ser_cfg.cpu_mask = p_usw_chip_master[lchip]->normal_affinity_mask;

    for (pp_id = SYS_PP_BASE(lchip); pp_id < (SYS_PP_NUM(lchip) + SYS_PP_BASE(lchip)); pp_id++)
    {
        CTC_ERROR_RETURN(drv_sdb_init(pp_id, &ser_cfg));
    }

    CTC_ERROR_RETURN(drv_ser_init(lchip, &ser_cfg));
    drv_ser_register_hw_reset_cb(lchip, DRV_SER_HW_RESET_CB_TYPE_DATAPATH, _sys_usw_dmps_reset_hw_datapath_proc);
    return CTC_E_NONE;
}


int32
sys_usw_chip_show_ser_status(uint8 lchip)
{

    LCHIP_CHECK(lchip);
    CTC_ERROR_RETURN(  drv_ser_get_cfg( lchip, DRV_SER_CFG_TYPE_SHOW_SER_STAUTS, NULL));

    return CTC_E_NONE;
}

int32
sys_usw_chip_set_tcam_scan_cfg(uint8 lchip, uint32 burst_entry_num, uint32 burst_interval)
{
    drv_ser_scan_info_t ecc_cfg;

    sal_memset(&ecc_cfg,0,sizeof(ecc_cfg));
    ecc_cfg.burst_entry_num = burst_entry_num;
    ecc_cfg.burst_interval  = burst_interval;
    CTC_ERROR_RETURN(  drv_ser_set_cfg( lchip, DRV_SER_CFG_TYPE_TCAM_SCAN_INFO, &ecc_cfg));

    return CTC_E_NONE;
}

/**
 @brief access type switch interface
*/
int32
sys_usw_chip_set_access_type(uint8 lchip, ctc_chip_access_type_t access_type)
{

    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "set access, access_type:%d\n", access_type);

    if (access_type >= CTC_CHIP_MAX_ACCESS_TYPE)
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(drv_set_access_type(lchip, (drv_access_type_t)access_type));
    return CTC_E_NONE;
}

#if 0
/**
 @brief access type switch interface
*/
int32
sys_usw_chip_get_access_type(uint8 lchip, ctc_chip_access_type_t* p_access_type)
{
    drv_access_type_t drv_access;

    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_ERROR_RETURN(drv_get_access_type(lchip, &drv_access));
    *p_access_type = (ctc_chip_access_type_t)drv_access;

    return CTC_E_NONE;

}
#endif

uint16
sys_usw_get_core_freq(uint8 lchip, uint8 type)
{
   return sys_usw_dmps_get_core_clock(lchip, type);
}

int32
sys_usw_chip_get_device_info(uint8 lchip, ctc_chip_device_info_t* p_device_info)
{
    uint32      cmd = 0;
    DevId_m    read_device_id;
    uint32      tmp_device_id = 0;
    uint32      get_device_id = 0;
    uint32      get_version_id = 0;
    uint32      efuse_value[3] = {0};
    int32      ret = 0;
    uint8       i = 0;
    char *chip_name_ext  = "CTC";

    CTC_PTR_VALID_CHECK(p_device_info);
    

    cmd = DRV_IOR(DevId_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &read_device_id));

    tmp_device_id = GetDevId(V,deviceId_f,&read_device_id);

    get_version_id = tmp_device_id & 0x0F;
    get_device_id  = (tmp_device_id >> 4) & 0x0F;


    switch(get_device_id)
    {
    case 0x07:
        p_device_info->device_id = SYS_CHIP_DEVICE_ID_USW_CTC7148;
        sal_strcpy(p_device_info->chip_name, "CTC7148");
        break;
    case 0x08:
        p_device_info->device_id = SYS_CHIP_DEVICE_ID_USW_CTC7132;
        sal_strcpy(p_device_info->chip_name, "CTC7132");
        break;
    case 0x09:
        p_device_info->device_id = SYS_CHIP_DEVICE_ID_USW_CTC8180;
        sal_strcpy(p_device_info->chip_name, "CTC8180");
        break;
    case 0x0b:
        p_device_info->device_id = SYS_CHIP_DEVICE_ID_USW_CTC9260;
        sal_strcpy(p_device_info->chip_name, "CTC9260");
        break;
    case 0x0c:
        p_device_info->device_id = SYS_CHIP_DEVICE_ID_USW_CTC8120;
        sal_strcpy(p_device_info->chip_name, "CTC8120");
        break;
    default:
        p_device_info->device_id  = SYS_CHIP_DEVICE_ID_INVALID;
        sal_strcpy(p_device_info->chip_name, "Not Support Chip");
        break;
    }
    p_device_info->version_id = get_version_id;
    if (DRV_IS_AT(lchip))
    {
        char *chip_name[] =
        {
            "Not Support Chip",
            "CTC9260",
            "CTC9262",
            "CTC9280",
            "CTC9282"
        };
        uint32 chip_sub_type = DRV_CHIP_SUB_TYPE(lchip);
        CTC_MAX_VALUE_CHECK(chip_sub_type, DRV_CHIP_SUB_TYPE_MAX - 1);
        if(CTC_MAX_CHIP_NAME_LEN < sal_strlen(chip_name[chip_sub_type]))
        {
            return CTC_E_NO_MEMORY;
        }
        sal_strncpy(p_device_info->chip_name, chip_name[chip_sub_type], sal_strlen(chip_name[chip_sub_type]));
    }
    else
    {
        ret = drv_read_efuse_data(lchip, 16, 3, efuse_value);
        if (efuse_value[0] && (CTC_E_NONE == ret))
        {
            uint32      tmp_value = 0;
            if (efuse_value[0] == 0x35313138 || efuse_value[0] == 0x33313234)
            {
                uint8 tmp = efuse_value[0] >> 24;
                uint8 efuse_ext = efuse_value[2] >> 24;
                if (efuse_ext)
                {
                    efuse_value[0] = (efuse_value[0] << 8) | efuse_ext;
                    efuse_value[1] = (efuse_value[1]&0xFFFFFF00) | tmp;
                }
            }
            tmp_value  = sal_htonl(efuse_value[0]);
            efuse_value[0] = sal_htonl(efuse_value[1]);
            efuse_value[1] = tmp_value;
            for (i = 0; i < 8; i++)
            {
                p_device_info->chip_name[i] = ((uint8 *)efuse_value)[i];
            }
            sal_strncpy(p_device_info->chip_name, chip_name_ext, sal_strlen(chip_name_ext));
            p_device_info->chip_name[8] = '\0';
            CTC_ERROR_RETURN(drv_read_efuse_data(lchip, 2, 1, efuse_value));
            p_device_info->version_id = (efuse_value[0] >> 24)&0xF;
            p_device_info->version_id = (p_device_info->device_id == SYS_CHIP_DEVICE_ID_USW_CTC7132 && 2 == p_device_info->version_id) ? 3 : p_device_info->version_id;
        }
    }
    return CTC_E_NONE;
}

int32 sys_usw_wb_show_module_version(uint8 lchip)
{
    char ver_str[20];

    if (!CTC_WB_ENABLE(lchip))
    {
        CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "warmboot is not enable!\n");
        return CTC_E_NOT_READY;
    }

    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_L2 >> 16, SYS_WB_VERSION_L2 & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "L2", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_SCL >> 16, SYS_WB_VERSION_SCL & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "SCL", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_ACL >> 16, SYS_WB_VERSION_ACL & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "ACL", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_QOS >> 16, SYS_WB_VERSION_QOS & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Qos", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_OAM >> 16, SYS_WB_VERSION_OAM & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "OAM", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_APS >> 16, SYS_WB_VERSION_APS & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "APS", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_PTP >> 16, SYS_WB_VERSION_PTP & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "PTP", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_PORT >> 16, SYS_WB_VERSION_PORT & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Port", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_VLAN >> 16, SYS_WB_VERSION_VLAN & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "Vlan", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_CHIP >> 16, SYS_WB_VERSION_CHIP & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Chip", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_L3IF >> 16, SYS_WB_VERSION_L3IF & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "L3IF", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_IPUC >> 16, SYS_WB_VERSION_IPUC & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "IPUC", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_IPMC >> 16, SYS_WB_VERSION_IPMC & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "IPMC", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_WLAN >> 16, SYS_WB_VERSION_WLAN & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Wlan", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_MPLS >> 16, SYS_WB_VERSION_MPLS & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "MPLS", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_IPFIX >> 16, SYS_WB_VERSION_IPFIX & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Ipfix", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_STATS >> 16, SYS_WB_VERSION_STATS & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Stats", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_DOT1AE >> 16, SYS_WB_VERSION_DOT1AE & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "Dot1ae", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_MIRROR >> 16, SYS_WB_VERSION_MIRROR & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Mirror", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_NEXTHOP >> 16, SYS_WB_VERSION_NEXTHOP & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Nexthop", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_OVERLAY >> 16, SYS_WB_VERSION_OVERLAY & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "Overlay", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_SECURITY >> 16, SYS_WB_VERSION_SECURITY & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Security", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_LINKAGG >> 16, SYS_WB_VERSION_LINKAGG & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Linkagg", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_STACKING >> 16, SYS_WB_VERSION_STACKING & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "Stacking", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_DATAPATH >> 16, SYS_WB_VERSION_DATAPATH & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Datapath", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_IP_TUNNEL >> 16, SYS_WB_VERSION_IP_TUNNEL & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "IP-Tunnel", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_ADV_VLAN >> 16, SYS_WB_VERSION_ADV_VLAN & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "Adv-Vlan", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_SYNCETHER >> 16, SYS_WB_VERSION_SYNCETHER & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "SyncE", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_REGISTER >> 16, SYS_WB_VERSION_REGISTER & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Register", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_INTER_PORT >> 16, SYS_WB_VERSION_INTER_PORT & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "Inter-Port", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_PACKET >> 16, SYS_WB_VERSION_PACKET & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Packet", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_SRV6 >> 16, SYS_WB_VERSION_SRV6 & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "SRv6", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_DTEL >> 16, SYS_WB_VERSION_DTEL & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "Dtel", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_MONITOR >> 16, SYS_WB_VERSION_MONITOR & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Monitor", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_SC_OAM >> 16, SYS_WB_VERSION_SC_OAM & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |", "Sc-OAM", ver_str);
    sal_sprintf(ver_str, "v%d.%d", SYS_WB_VERSION_XDATA >> 16, SYS_WB_VERSION_XDATA & 0xFFFF);
    CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "| %-10s: %-6s |\n", "Xdata", ver_str);

    return CTC_E_NONE;
}
int32
sys_usw_chip_set_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    CTC_PTR_VALID_CHECK(p_value);
    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "lchip:%d chip_prop:0x%x \n", lchip, chip_prop);

    switch(chip_prop)
    {
        case CTC_CHIP_PROP_CPU_PORT_EN:
            CTC_ERROR_RETURN(_sys_usw_chip_set_eth_cpu_cfg(lchip, (ctc_chip_cpu_port_t*)p_value));
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }
    return CTC_E_NONE;
}

int32
sys_usw_chip_get_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    CTC_PTR_VALID_CHECK(p_value);
    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_CHIP_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "lchip:%d chip_prop:0x%x \n", lchip, chip_prop);

    switch(chip_prop)
    {
        case CTC_CHIP_PROP_CPU_PORT_EN:
            CTC_ERROR_RETURN(_sys_usw_chip_get_eth_cpu_cfg(lchip, (ctc_chip_cpu_port_t*)p_value));
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }
    return CTC_E_NONE;
}

uint8
sys_usw_vchip_get_pp_base(uint8 lchip)
{
    return drv_vchip_get_pp_base(lchip);
}

uint8
sys_usw_vchip_get_core_pp_base(uint8 lchip)
{
    return drv_vchip_get_core_pp_base(lchip);
}

uint8
sys_usw_vchip_get_pp_num(uint8 lchip)
{
    return drv_vchip_get_pp_num(lchip);
}

uint8
sys_usw_vchip_get_pp_bmp(uint8 lchip)
{
    return  drv_vchip_get_pp_bmp(lchip);
}

int32
sys_usw_chip_free_rsv_resource(uint8 lchip)
{
    if (!DRV_FROM_AT(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }
    /*Free dsfwd1 on brguc nh when overlay tunnel is to AC */
    sys_usw_nh_free_rsv_resource(lchip);
    /*Free scl inner group */
    sys_usw_scl_free_inner_group(lchip);
    return CTC_E_NONE;
    
}

